package com.you.weixinpay.task;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.you.weixinpay.domain.entity.TOrderInfo;
import com.you.weixinpay.enums.OrderStatus;
import com.you.weixinpay.enums.PaymentType;
import com.you.weixinpay.service.TOrderInfoService;
import com.you.weixinpay.service.WxPayService;
import com.you.weixinpay.utils.AliPayNativeUtils;
import com.you.weixinpay.utils.WeChatNativePayUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
@RequiredArgsConstructor
public class PayTask {

    // 订单超时时间(分钟)
    private static final int ORDER_TIMEOUT_MINUTES = 15;
    // 定时任务执行间隔(秒)
    private static final int TASK_INTERVAL_SECONDS = 30;

    private final WxPayService wxPayService;
    private final TOrderInfoService orderInfoService;
    private final WeChatNativePayUtil weChatNativePayUtil;
    private final AliPayNativeUtils aliPayNativeUtils;

    /**
     * 定时检查并处理超时未支付订单
     */
    @Scheduled(cron = "0/" + TASK_INTERVAL_SECONDS + " * * * * ?")
    public void checkAndProcessTimeoutOrders() {
        log.info("开始执行支付订单超时检查任务【start】");

        try {
            LocalDateTime timeoutThreshold = LocalDateTime.now().minusMinutes(ORDER_TIMEOUT_MINUTES);
            List<TOrderInfo> unpaidOrders = orderInfoService.getUnpaidOrders(timeoutThreshold);

            if (CollectionUtils.isEmpty(unpaidOrders)) {
                log.info("未发现超时未支付订单");
                return;
            }

            log.info("共发现{}笔超时未支付订单需要处理", unpaidOrders.size());
            processUnpaidOrders(unpaidOrders);

        } catch (Exception e) {
            log.error("支付订单超时检查任务执行异常", e);
        } finally {
            log.info("支付订单超时检查任务执行完毕【end】");
        }
    }

    /**
     * 处理未支付订单
     */
    private void processUnpaidOrders(List<TOrderInfo> unpaidOrders) {
        unpaidOrders.forEach(order -> {
            try {
                log.info("【start】开始处理订单[{}], 支付类型: {}", order.getOrderNo(), order.getPaymentType());

                if (isWeChatPayOrder(order)) {
                    processWeChatPayOrder(order);
                } else if (isAliPayOrder(order)) {
                    processAliPayOrder(order);
                } else {
                    log.warn("未知支付类型的订单[{}], 支付类型: {}", order.getOrderNo(), order.getPaymentType());
                }

                log.info("【end】订单[{}]处理完成", order.getOrderNo());
            } catch (Exception e) {
                log.error("处理订单[{}]异常", order.getOrderNo(), e);
                // 异常情况下关闭订单
                closeOrderWithStatus(order, OrderStatus.CLOSED);
            }
        });
    }

    /**
     * 处理微信支付订单
     */
    private void processWeChatPayOrder(TOrderInfo order) throws Exception {
        String orderNo = order.getOrderNo();
        String tradeState = wxPayService.queryOrder(orderNo);

        switch (tradeState) {
            case "SUCCESS":
                updateOrderStatus(order, OrderStatus.SUCCESS, "微信支付成功");
                break;
            case "NOTPAY":
                weChatNativePayUtil.closeOrder(orderNo);
                closeOrderWithStatus(order, OrderStatus.CLOSED, "微信支付超时未支付");
                break;
            default:
                updateOrderStatus(order, tradeState, "微信支付状态更新");
        }
    }

    /**
     * 处理支付宝订单
     */
    private void processAliPayOrder(TOrderInfo order) {
        String orderNo = order.getOrderNo();

        try {
            String aliPayResult = aliPayNativeUtils.queryOrder(orderNo);

            if (aliPayResult == null) {
                closeOrderWithStatus(order, OrderStatus.CLOSED, "支付宝订单查询失败");
                return;
            }

            if (aliPayResult.contains("\"trade_status\":\"TRADE_SUCCESS\"")) {
                updateOrderStatus(order, OrderStatus.SUCCESS, "支付宝支付成功");
            } else if (aliPayResult.contains("\"trade_status\":\"WAIT_BUYER_PAY\"")) {
                aliPayNativeUtils.closeOrder(orderNo);
                closeOrderWithStatus(order, OrderStatus.CLOSED, "支付宝支付超时未支付");
            } else {
                closeOrderWithStatus(order, OrderStatus.CLOSED, "支付宝支付状态异常");
            }
        } catch (Exception e) {
            log.error("处理支付宝订单[{}]异常", orderNo, e);
            closeOrderWithStatus(order, OrderStatus.CLOSED, "支付宝订单处理异常");
        }
    }

    /**
     * 判断是否为微信支付订单
     */
    private boolean isWeChatPayOrder(TOrderInfo order) {
        return Objects.equals(order.getPaymentType(), PaymentType.WXPAY.getType());
    }

    /**
     * 判断是否为支付宝订单
     */
    private boolean isAliPayOrder(TOrderInfo order) {
        return Objects.equals(order.getPaymentType(), PaymentType.ALIPAY.getType());
    }

    /**
     * 更新订单状态
     */
    private void updateOrderStatus(TOrderInfo order, OrderStatus status, String remark) {
        order.setOrderStatus(status.getType());
        orderInfoService.updateById(order);
        log.info("订单[{}]状态更新为: {}, 原因: {}", order.getOrderNo(), status, remark);
    }

    /**
     * 更新订单状态(重载)
     */
    private void updateOrderStatus(TOrderInfo order, String status, String remark) {
        order.setOrderStatus(status);
        orderInfoService.updateById(order);
        log.info("订单[{}]状态更新为: {}, 原因: {}", order.getOrderNo(), status, remark);
    }

    /**
     * 关闭订单并设置状态
     */
    private void closeOrderWithStatus(TOrderInfo order, OrderStatus status) {
        closeOrderWithStatus(order, status, null);
    }

    /**
     * 关闭订单并设置状态(带原因)
     */
    private void closeOrderWithStatus(TOrderInfo order, OrderStatus status, String reason) {
        order.setOrderStatus(status.getType());
        orderInfoService.updateById(order);
        String logMsg = reason != null ?
                String.format("订单[%s]已关闭, 状态: %s, 原因: %s", order.getOrderNo(), status, reason) :
                String.format("订单[%s]已关闭, 状态: %s", order.getOrderNo(), status);
        log.info(logMsg);
    }
}